package org.erepublik.company.scanner;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.cyberneko.html.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class ErepublikCompanyForSaleSite {

    String website;
    public ErepublikCompanyForSaleSite(String website) {
        this.website = website;
    }
    
    public boolean hasNextPage() {
        
        Pattern p = Pattern.compile("class=\"next \" title=\"Go to next page\">Next</a></li>");

        Matcher m = p.matcher(website);

        return m.find();
    }
    
    public HashMap<Integer, Double> getCompaniesIdAndPrice() {
        
        DOMParser parser = new DOMParser();
        

        
        InputSource bla = null;
       
            
     
        try {
            bla = new InputSource( new ByteArrayInputStream(website.getBytes("UTF-8")) );
            parser.parse(bla);
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        Document page = parser.getDocument();
        Node mainnode = getPriceTable( page );
        
        HashMap<Integer, Double> companies = new HashMap<Integer, Double>();
        ArrayList<Node> nodes = getTDWithPrice(mainnode);
        for (Node node : nodes) {
            Double price = getPrice(node);
            Integer id = getId(node);
            companies.put(id, price);
        }
        
        return companies;
    }

    
    private Integer getId(Node node) { 

        return Integer.parseInt( node.getPreviousSibling().getPreviousSibling().getAttributes().getNamedItem("id").getNodeValue().split("_")[1] );
    }

    private Double getPrice(Node node) {
        double price =  Integer.parseInt( node.getFirstChild().getNextSibling().getFirstChild().getNodeValue() );
        price += Double.parseDouble( node.getFirstChild().getNextSibling().getNextSibling().getNextSibling().getFirstChild().getNodeValue() );
        return price;
    }

    private ArrayList<Node> getTDWithPrice(Node node) {
      
        ArrayList<Node> nodes = new ArrayList<Node>();
        Node TRoll = node.getFirstChild().getNextSibling();
        while (TRoll.getNextSibling().getNextSibling()!=null) {
            Node nodeWithPrice = TRoll.getFirstChild().getNextSibling()
                    .getNextSibling().getNextSibling().getNextSibling().getNextSibling();
            nodes.add(nodeWithPrice);
            
            TRoll = TRoll.getNextSibling().getNextSibling();
        }
        
        
        return nodes;
    }


    
    
    // zwraca czesc drzewa DOM, reprezentujacego tabele z podatkami
    public Node getPriceTable(Node page) {
        Node node = page.getFirstChild();

        while (node != null) {
            if (node.getNodeName().equals("TBODY") && containsAttribute(node)) {
                return node;
            }
            Node child = getPriceTable(node);

            if (child != null)
                return child;
            node = node.getNextSibling();
        }

        return null;
    }

    private boolean containsAttribute(Node node) {
        return node.getAttributes().getNamedItem("class") != null
                && node.getAttributes().getNamedItem("class").getNodeValue().equals("main industry_sorted");
    }
    
    
    
    
    public static void main(String[] args) {
        
        InputStream url = ErepublikCompanyForSaleSite.class.getClass().getResourceAsStream( "/xmlSamples/companyForSale.html" );
        
        ErepublikCompanyForSaleSite zis = new ErepublikCompanyForSaleSite( slurp(url) );
        
        HashMap<Integer, Double> map = zis.getCompaniesIdAndPrice();
        for (Integer id : map.keySet()) {
            System.out.println(id + "  " + map.get(id));
        }
        
        System.out.println( zis.hasNextPage() );
        
    }
    
    
    
    
    public static String slurp (InputStream in)  {
        StringBuffer out = new StringBuffer();
        byte[] b = new byte[4096];
        try {
            for (int n; (n = in.read(b)) != -1;) {
                out.append(new String(b, 0, n));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toString();
    }
    
    
    
    
    
    
}
